/*
 * Package il.ac.biu.cs.grossmm.api.server
 * File LoaderBase.java
 * Created on Sep 5, 2006
 *
 */
package il.ac.biu.cs.grossmm.api.server;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Provides a caching capability for loaders that extends this class.
 */
public abstract class LoaderSupport implements Loader {
	Map<Object, Wrapped> cache;
	
	Lock lock = new ReentrantLock();

	public LoaderSupport()
	{
		cache = new HashMap<Object, Wrapped>();
	}

	public LoaderSupport(int initialCapacity)
	{
		cache = new HashMap<Object, Wrapped>(initialCapacity);
	}

	/**
	 * The superclass may not override this method, instead it must implement
	 * the <tt>doLoad</tt> method
	 */
	public final Wrapped load(Wrapper wrapper, Object hint)
		throws Exception
	{
		lock.lock();
		
		Wrapped w;
		try {
		
			w = cache.get(hint);
			if (w != null)
				return w;
	
			w = doLoad(wrapper, hint);
	
			if (w != null)
				cache.put(hint, w);
		} finally {
			lock.unlock();
		}

		return w;
	}

	/**
	 * This method is invoked with semantics equivalent to <tt>Loader.load</tt>
	 * but only for the cases when the object with this hint was not loaded
	 * before
	 * 
	 * 
	 * @param wrapper
	 *            wrapper to use to wrap loaded object
	 * @param hint
	 *            server object hint
	 * @return wrapped server object
	 * @throws Exception
	 */
	protected abstract Wrapped doLoad(Wrapper wrapper, Object hint)
		throws Exception;

}
